#include "Timer.hpp"

Timer::Timer(unsigned int interval_ms, std::function<void(uint64_t)> taskFunc)
    : interval(interval_ms), task(std::move(taskFunc)), running(false) {}

Timer::~Timer() {
    stop();
}

void Timer::start() {
    if (running) return;
    running = true;
    worker = std::thread(&Timer::run, this);
}

void Timer::stop() {
    running = false;
    if (worker.joinable()) worker.join();
}

uint64_t Timer::getCurrentTimeMicroseconds() {
    using namespace std::chrono;
    return duration_cast<microseconds>(steady_clock::now().time_since_epoch()).count();
}

void Timer::run() {
    while (running) {
        auto start_time = std::chrono::steady_clock::now();
        uint64_t now_us = getCurrentTimeMicroseconds();

        task(now_us);

        {
            std::lock_guard<std::mutex> lock(mtx);
            is_ready = true;
        }
        cv.notify_one();

        std::this_thread::sleep_until(start_time + std::chrono::milliseconds(interval));
    }
}

void Timer::wait() {
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, [&] { return is_ready; });
    is_ready = false;
}
